﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;
using System.Drawing.Design;

namespace FdControlls.Fonts
{
    /// <summary>
    /// 图标控件
    /// </summary>
    public partial class PicIcon : PictureBox
    {
        #region 构造方法

        /// <summary>
        /// 初始化图标外观
        /// </summary>
        public PicIcon() : this(EIconType.ICON_0, 16, Color.DimGray, Color.Black, false, null) { }

        /// <summary>
        /// 初始化图标外观
        /// </summary>
        /// <param name="type">图标类型</param>
        /// <param name="size">图表大小</param>
        /// <param name="normalColor">颜色</param>
        /// <param name="hoverColor">颜色</param>
        /// <param name="selectable">暂时无用</param>
        /// <param name="toolTip">提示信息</param>
        public PicIcon(EIconType type, int size, Color normalColor, Color hoverColor, bool selectable, string toolTip)
        {
            IconFont = null;
            BackColor = Color.Transparent;

            // need more than this to make picturebox selectable
            if (selectable)
            {
                SetStyle(ControlStyles.Selectable, true);
                TabStop = true;
            }

            Width = size;
            Height = size;

            IconType = type;

            InActiveColor = normalColor;
            ActiveColor = hoverColor;

            ToolTipText = toolTip;

            MouseEnter += Icon_MouseEnter;
            MouseLeave += Icon_MouseLeave;
        }

        #endregion

        #region 公共的

        #region 公有属性

        /// <summary>
        /// 需要显示的字体图标
        /// </summary>
        [Description("字体图表编码")]
        [Browsable(true)]
        [Editor(typeof(ScopeDropDownEditor), typeof(UITypeEditor))]
        public EIconType IconType
        {
            get { return _iconType; }
            set
            {
                _iconType = value;
                IconChar = char.ConvertFromUtf32((int)value);
                Invalidate();
            }
        }

        /// <summary>
        /// 提示的信息
        /// </summary>
        /// <value>
        /// 文本类型
        /// </value>
        [Localizable(true)]
        public string ToolTipText
        {
            get { return _tooltip; }
            set
            {
                _tooltip = value;
                if (value != null)
                {
                    _tT.IsBalloon = true;
                    _tT.ShowAlways = true;
                    _tT.SetToolTip(this, value);
                }
            }
        }

        /// <summary>
        /// 获取焦点时候的颜色
        /// </summary>
        public Color ActiveColor
        {
            get { return _activeColor; }
            set
            {
                _activeColor = value;
                ActiveBrush = new SolidBrush(value);
                Invalidate();
            }
        }

        /// <summary>
        /// 失去焦点时候的颜色
        /// </summary>
        public Color InActiveColor
        {
            get { return _inActiveColor; }
            set
            {
                _inActiveColor = value;
                InActiveBrush = new SolidBrush(value);
                IconBrush = InActiveBrush;
                Invalidate();
            }
        }

        /// <summary>
        /// 宽度
        /// </summary>
        /// <returns></returns>
        public new int Width
        {
            set
            {
                base.Width = value;
                IconFont = null;
                Invalidate();
            }
            get { return base.Width; }
        }

        /// <summary>
        /// 高度
        /// </summary>
        /// <returns></returns>
        public new int Height
        {
            set
            {
                base.Height = value;
                IconFont = null;
                Invalidate();
            }
            get { return base.Height; }
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 设置图标
        /// </summary>
        /// <param name="newValue">新的图标字符编码</param>
        public void SetIconChar(char newValue)
        {
            IconChar = newValue.ToString();
            Invalidate();
        }

        #endregion

        #endregion

        #region 私有 属性 方法
        private EIconType _iconType = EIconType.ICON_0;
        private string _tooltip = null;
        private Color _activeColor = Color.Black;
        private Color _inActiveColor = Color.Black;
        private ToolTip _tT = new ToolTip();
        private string IconChar { get; set; }
        private Font IconFont { get; set; }
        private Brush IconBrush { get; set; }
        private Brush ActiveBrush { get; set; }
        private Brush InActiveBrush { get; set; }

        protected void Icon_MouseLeave(object sender, EventArgs e)
        {
            IconBrush = InActiveBrush;
            Invalidate();
        }
        protected void Icon_MouseEnter(object sender, EventArgs e)
        {
            IconBrush = ActiveBrush;
            Invalidate();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            var graphics = e.Graphics;

            graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            if (IconFont == null)
            {
                SetFontSize(graphics);
            }

            SizeF stringSize = graphics.MeasureString(IconChar, IconFont, Width);
            float w = stringSize.Width;
            float h = stringSize.Height;

            float left = (Width - w) / 2;
            float top = (Height - h) / 2;

            graphics.DrawString(IconChar, IconFont, IconBrush, new PointF(left, top));

            base.OnPaint(e);

            if (Focused)
            {
                var rc = this.ClientRectangle;
                rc.Inflate(-2, -2);
                ControlPaint.DrawFocusRectangle(e.Graphics, rc);
            }
        }

        private void SetFontSize(Graphics g)
        {
            IconFont = GetAdjustedFont(g, IconChar, Width, Height, 4, true);
        }

        private Font GetIconFont(float size)
        {
            return new Font(FontRead.fonts.Families[0], size, GraphicsUnit.Point);
        }

        private Font GetAdjustedFont(Graphics g, string graphicString, int containerWidth, int maxFontSize, int minFontSize, bool smallestOnFail)
        {
            for (double adjustedSize = maxFontSize; adjustedSize >= minFontSize; adjustedSize = adjustedSize - 0.5)
            {
                Font testFont = GetIconFont((float)adjustedSize);
                SizeF adjustedSizeNew = g.MeasureString(graphicString, testFont);
                if (containerWidth > Convert.ToInt32(adjustedSizeNew.Width))
                {
                    return testFont;
                }
            }
            return GetIconFont(smallestOnFail ? minFontSize : maxFontSize);
        }
        #endregion
    }
}
